﻿using Dpy.MathWinRT.Geometry.Geometry2D;
using System;
using System.Linq;

namespace BouncingBallGame.ViewModels.ShapeViewModels
{
    public class RectangleViewModel : ShapeViewModelBase
    {
        #region Fields

        private double x;
        private double y;
        private double width;
        private double height;
        private double rotation;
        private LineSegment2D[] sides = null;

        #endregion


        #region Properties

        public LineSegment2D[] Sides
        {
            get
            {
                if (this.sides == null)
                {
                    this.CalculateSides();
                }

                return this.sides;
            }
        }

        public override double X
        {
            get
            {
                return this.x;
            }
            set
            {
                if (this.x != value)
                {
                    this.x = value;
                    this.OnPropertyChanged("X");
                }
            }
        }

        public override double Y
        {
            get
            {
                return this.y;
            }
            set
            {
                if (this.y != value)
                {
                    this.y = value;
                    this.OnPropertyChanged("Y");
                }
            }
        }

        public double Width
        {
            get
            {
                return this.width;
            }
            set
            {
                if (this.width != value)
                {
                    this.width = value;
                    this.OnPropertyChanged("Width");
                }
            }
        }

        public double Height
        {
            get
            {
                return this.height;
            }
            set
            {
                if (this.height != value)
                {
                    this.height = value;
                    this.OnPropertyChanged("Height");
                }
            }
        }

        public double Rotation
        {
            get
            {
                return this.rotation;
            }
            set
            {
                if (this.rotation != value)
                {
                    this.rotation = value;
                    this.OnPropertyChanged("Rotation");
                }
            }
        }

        #endregion


        #region Constructors

        public RectangleViewModel(double x, double y, double height, double width, double rotation)
        {
            this.x = x;
            this.y = y;
            this.height = height;
            this.width = width;
            this.rotation = rotation;
            this.CalculateSides();
        }

        #endregion


        #region Methods

        public void CalculateSides()
        {
            double radians = this.rotation * (Math.PI / 180);

            Vector2D a = new Vector2D(this.x, this.y);
            Vector2D b = new Vector2D(this.width, 0).RotateCounterClockwise(radians) + a;
            Vector2D c = new Vector2D(0, this.height).RotateCounterClockwise(radians) + a;
            Vector2D d = new Vector2D(this.width, this.height).RotateCounterClockwise(radians) + a;

            this.sides = new LineSegment2D[4];

            this.sides[0] = new LineSegment2D(a, b);
            this.sides[1] = new LineSegment2D(b, d);
            this.sides[2] = new LineSegment2D(d, c);
            this.sides[3] = new LineSegment2D(c, a);
        }

        public override void Scale(double scaleFactor)
        {
            this.Width *= scaleFactor;
            this.Height *= scaleFactor;
            this.X *= scaleFactor;
            this.Y *= scaleFactor;
            this.CalculateSides();
        }

        public override void FitInSize(double maxWidth, double maxHeight)
        {
            double scaleFactor = (maxWidth / this.Width) * this.Height <= maxHeight
                ? (maxWidth / this.Width)
                : (maxHeight / this.Height);

            this.Scale(scaleFactor);
        }

        #endregion

        
    }
}
